package org.robert.export_client.excel.impl;

import com.alibaba.fastjson.JSON;
import com.robert.common.commonutil.util.DateUtils;
import com.robert.common.commonutil.util.LocalDateUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.CellStyle;
import org.robert.export_client.excel.metadata.ExcelDictEntity;
import org.robert.export_client.excel.metadata.ExcelHeadEntity;
import org.robert.export_client.excel.metadata.IBaseExcelWrite;
import org.robert.export_client.excel.util.ExcelUtil;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.*;

/**
 * ExcelWrtiteByDataService:
 *  备份， 这个算法json中字段在excel中必须是连续的排序，有瑕疵
 * @author zhaoshengtao
 * @date 2024/01/19
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ExcelWriteByDataService2 implements IBaseExcelWrite {

    private HSSFSheet sheet;

    public ExcelWriteByDataService2(HSSFSheet sheet) {
        this.sheet = sheet;
    }

    private int idSeq = 1;

    @Override
    public void doWrite(List<?> data, Class<?> clazz, List<ExcelHeadEntity> propertyNames) throws Exception {
        // 获取头
        HSSFRow row = null;//第一行
        HSSFCell cell = null;
        // 获取字段名
        Map<String, List<ExcelHeadEntity>> filedMap = getSortMap(propertyNames);
        int i = this.idSeq;
        // 遍历实体对象集合
        for (Object t : data) {
            int j = 0;
            row = ExcelUtil.createRow(sheet, i++, 250);
            for (List<ExcelHeadEntity> headEntities : filedMap.values()) {
                ExcelHeadEntity headEntity = headEntities.get(0);
                String fieldName = headEntity.getFieldName();
                // 如果大于一，说明需要解析
                if(headEntities.size() > 1){
                    Field field = getFieldByName(clazz, fieldName);
                    if (field != null) {
                        field.setAccessible(true);
                        Object value = field.get(t);
                        Object jsonValue = null;
                        if(value instanceof String){
                            // 解析json
                            Class jsonClazz = headEntity.getJsonClazz();
                            jsonValue = JSON.parseObject((String) value, jsonClazz);
                            for (ExcelHeadEntity jsonHead : headEntities) {
                                String subFieldName = jsonHead.getSubFieldName();
                                String fieldValue = this.setFiledByName(subFieldName, headEntity.getJsonClazz(), jsonValue, jsonHead);
                                cell = ExcelUtil.createCell(row, j, null);
                                cell.setCellValue(fieldValue);
                                j = j + 1;
                            }
                            continue;
                        }
                    }
                    for (int m= 0; m < headEntities.size(); m++) {
                        cell = ExcelUtil.createCell(row, j, null);
                        cell.setCellValue("N/A");
                        j = j + 1;
                    }
                }else{
                    String fieldValue = this.setFiledByName(fieldName, clazz, t, headEntity);
                    cell = ExcelUtil.createCell(row, j, null);
                    cell.setCellValue(fieldValue);
                    j = j + 1;
                }
            }
        }
        this.idSeq += data.size();
    }

    @Override
    public void doWrite(List<?> data, Class<?> clazz, List<ExcelHeadEntity> propertyNames, CellStyle cellStyle, Integer rowHeight) throws Exception {

    }

    private Field getFieldByName(Class<?> clazz, String fieldName) {
        try {
            return clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            return null;
        }
    }

    private String setFiledByName(String fieldName, Class clazz,Object t,ExcelHeadEntity headEntity) throws IllegalAccessException {
        Field field = getFieldByName(clazz, fieldName);
        if (field != null) {
            field.setAccessible(true);
            Object value = field.get(t);
            // 判断是否需要解析字典
            ExcelDictEntity dictEntity = headEntity.getDictEntity();
            if(dictEntity != null){
                return setDictValue(dictEntity, (String)value);
            }
            // 是否需要解析时间
            String dateFormat = headEntity.getDateFormat();
            if(StringUtils.isNotBlank(dateFormat)){
                // TODO 时间解析逻辑
                if (value instanceof LocalDateTime) {
                    return   LocalDateUtil.getFormatDate((LocalDateTime) value, dateFormat);
                }
                if (value instanceof Date) {
                    return DateUtils.getDate((Date) value, dateFormat);
                }
                return "N/A";
            }

            return String.valueOf(value);

        }
        return "N/A"; // 或者处理找不到属性的情况
    }

    private String setDictValue(ExcelDictEntity dictEntity, String attributeValue ){
        Map<String, String> map = dictEntity.getDictMap();
        // 是否需要分割
        if(dictEntity.isSplit()){
            String connect = dictEntity.getConnect();
            String spilt = dictEntity.getSpilt();
            if(StringUtils.isNotBlank(attributeValue)){
                String[] strings = attributeValue.split(spilt);
                StringBuilder builder = new StringBuilder();
                for (String string : strings) {
                    String s = map.get(string);
                    if(StringUtils.isNotBlank(s)){
                        builder.append(s).append(StringUtils.isNotBlank(connect) ? connect : spilt);
                    }
                }
                return String.valueOf(builder);
            }
        }else{
            return map.get(attributeValue);
        }
        return "N/A";
    }


    private TreeMap<String, List<ExcelHeadEntity>> getSortMap(List<ExcelHeadEntity> list){
        // 创建一个TreeMap，键是index，值是一个包含所有具有相同index的对象的列表
        TreeMap<String, List<ExcelHeadEntity>> sortedMap = new TreeMap<>();
        HashMap<String, String> cacheKeyMap = new HashMap<>();
        for (ExcelHeadEntity entity : list) {
            String key = entity.getColumnIndex() + "_" + entity.getFieldName();
            boolean flag = false;
            for (String s : sortedMap.keySet()) {
                String[] arr = s.split("_");
                if(arr[1].equals(entity.getFieldName())){
                    flag = true;
                    key = cacheKeyMap.get(arr[1]);
                }
            }
            if(flag){
                List<ExcelHeadEntity> excelHeadEntities = sortedMap.get(key);
                List<ExcelHeadEntity> objects = new ArrayList<>();
                objects.addAll(excelHeadEntities);
                objects.add(entity);
                sortedMap.put(key, objects);
            }else{
                if(!cacheKeyMap.containsKey(entity.getFieldName())){
                    cacheKeyMap.put(entity.getFieldName(), key);
                }

                sortedMap.put(key, Arrays.asList(entity));
            }
        }
        return sortedMap;
    }
}
